﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
using Interface;
using System.Reflection;
using System.Collections;

namespace mogco
{
    public class CMPMainWorker
    {
        private bool useDirectoryTree;
        private List<string> directoryPaths;
        private List<string> filePaths;
        private DirectoryInfo rootDirectory;

        /// <summary>
        /// Возвращает список директорий для обработки
        /// </summary>
        public List<string> DTreePaths
        {
            get { return directoryPaths; }
        }

        public List<string> FTreePaths
        {
            get { return filePaths; }
        }

        public DirectoryInfo RootDirectory
        {
            get { return rootDirectory; }
            set { rootDirectory = value; }
        }

        public bool UseDirectoryTree
        {
            get { return useDirectoryTree; }
            set { useDirectoryTree = value; }
        }

        public Hashtable Plugins
        {
            get;
            set;
        }

        public CMPMainWorker()
        {
            //initialization
            Plugins = new Hashtable();
            directoryPaths = new List<string>();
        }

        ///// <summary>
        ///// Формирует дерево библиотеки
        ///// </summary>
        ///// <param name="rootpath"></param>
        //public void GetFilesTree(string rootpath)
        //{
        //    FormDirectoryTree(rootpath, rootpath);

        //}

        //private void FormDirectoryTree(string rootpath, string nullLevelPath)
        //{
        //    DirectoryInfo[] subDirs = new DirectoryInfo(rootpath).GetDirectories();
        //    foreach (DirectoryInfo subDir in subDirs)
        //    {
        //        string currentPathInTree = subDir.FullName.Remove(0, nullLevelPath.Length); // удалить весь путь до выбранного каталога
        //        //this.FormFileTree(subDir);
        //        directoryPaths.Add(currentPathInTree);
        //        FormDirectoryTree(subDir.FullName, nullLevelPath);
        //    }
        //}

        ////private void FormFileTree(DirectoryInfo dinfo)
        ////{
        ////    //foreach (FileInfo finfo in dinfo.GetFiles())
        ////    //{

        ////    //}
        ////}

        //public void CreateDirectoryTree(string rootpath)
        //{
        //    if (directoryPaths.Capacity == 0)
        //        throw new Exception("Zero tree elements");
        //    foreach (string currentPath in directoryPaths)
        //    {
        //        string newDirectoryPath = rootpath + currentPath;
        //        try
        //        {
        //            if (!Directory.Exists(newDirectoryPath))
        //                Directory.CreateDirectory(newDirectoryPath);
        //        }
        //        catch (Exception e)
        //        {
        //            Logger.txtLogger.WriteMessage("Can't create folder" + e.ToString());
        //        }
        //    }
        //}

        /// <summary>
        /// Функция формирует пути для новых файлов и, если указано, создает папки
        /// </summary>
        /// <param name="sourcePath"></param>
        /// <param name="destDirectory"></param>
        /// <param name="mask"></param>
        /// <returns></returns>
        public string FormNewPathes(string sourcePath, string destDirectory, string mask)
        {
            string _destPath = destDirectory;
            FileInfo _fileInfo = new FileInfo(sourcePath);
            string _fileName = _fileInfo.Name;
            string _sourceDirectory;
            string _res_file_name = "";


            string ext = "";
            switch (Settings.xml.SaveFormat)
            {
                case mogco.Structs.Structs.PictureExtensions.JPG:
                    ext = ".jpg";
                    break;
                case mogco.Structs.Structs.PictureExtensions.PNG:
                    ext = ".png";
                    break;
                default:
                    ext = ".jpg";
                    break;
            }
            _fileName = _fileName.Replace(_fileInfo.Extension, ""); // удаление расширения

            // формирование имени файла
            // ------------------------------------
            Regex pat = new Regex("\\[.\\]", RegexOptions.IgnoreCase); // найти все ключи
            Match match = pat.Match(mask);
            List<string> matchs = new List<string>();
            while (match.Success)
            {
                matchs.Add(match.Value);
                match = match.NextMatch();
            }
            foreach (var opt in matchs)
            {
                switch (opt)
                {
                    case "[F]":     //добавить оригинальное имя файла
                        _res_file_name += _fileName;
                        break;
                    case "[D]":     // добавить текущую дату без времени
                        _res_file_name += DateTime.Now.Date.ToString("yyyy-MMMM-dd");
                        break;
                    case "[R]":
                        _res_file_name += Settings.xml.Resolution.Y.ToString() + "x" + Settings.xml.Resolution.X.ToString();
                        break;
                    default:
                        break;
                }
            }
            // ---------------------------------------

            DirectoryInfo sourceDirectory = Directory.GetParent(sourcePath);
            // В какую, собственно, директорию сохранять
            if (useDirectoryTree)
            {
                // currentNewDirectoryPath - кусок пути, который создавать в новой медиабиблиотеке
                string currentNewDirectoryPath = sourceDirectory.FullName.Remove(0, rootDirectory.FullName.Length); // удалить весь путь до выбранного каталога
                _destPath += currentNewDirectoryPath + "\\";
                try
                {
                    if (!Directory.Exists(_destPath))
                        Directory.CreateDirectory(_destPath);
                }
                catch (Exception e)
                {
                    Logger.txtLogger.WriteMessage("Can't create directory" + e.ToString());
                }
            }
            else
            {
                if (destDirectory == null && destDirectory.Length == 0) // если не задана папка назначения, то сохранить туда же + small
                {
                    _sourceDirectory = _fileInfo.Directory.FullName;
                    if (!Directory.Exists(_sourceDirectory + "\\small"))
                        Directory.CreateDirectory(_sourceDirectory + "\\small");
                    _destPath = _sourceDirectory + "\\small\\";
                }
                else // иначе юзать заданную
                {
                    _destPath = destDirectory + "\\";
                }
            }

            _destPath += _res_file_name + ext;

            return _destPath;
        }

        public void GRFilesByPath(string path, ref List<string> files)
        {
            // local files
            List<string> _files = new List<string>();
            string searchPattern = "";
            string[] splitSearchPatter;
            SearchOption options = SearchOption.TopDirectoryOnly;
            if (Settings.xml.SearchFilesRecursively)
                options = SearchOption.AllDirectories;
            if ((Settings.xml.OpenPictureExtensions & mogco.Structs.Structs.PictureExtensions.None) == mogco.Structs.Structs.PictureExtensions.None)
            {
                if ((Settings.xml.OpenPictureExtensions & mogco.Structs.Structs.PictureExtensions.JPG) == mogco.Structs.Structs.PictureExtensions.JPG)
                    searchPattern += "*.jpg;";
                if ((Settings.xml.OpenPictureExtensions & mogco.Structs.Structs.PictureExtensions.PNG) == mogco.Structs.Structs.PictureExtensions.PNG)
                    searchPattern += "*.png";
                splitSearchPatter = searchPattern.Split(';');
                try
                {
                    foreach (string pattern in splitSearchPatter)
                    {
                        _files.AddRange(Directory.GetFiles(path, pattern, options));
                    }
                }
                catch (Exception e)
                {
                    Logger.txtLogger.WriteMessage("Can't get list of files." + e.ToString());
                    return;
                }
                files = _files;
            }
        }

        public void LoadPlugins()
        {
            string folder = System.AppDomain.CurrentDomain.BaseDirectory + "\\plugins";
            if (!Directory.Exists(folder))
            {
                Logger.txtLogger.WriteMessage("Plugins directory not exists. Can't load plugins");
                return;
            }
            string[] files = Directory.GetFiles(folder, "*.dll");

            foreach(string file in files)
                try
                {
                    Assembly assembly = Assembly.LoadFile(file);

                    foreach(Type type in assembly.GetTypes())
                    {
                        Type iface = type.GetInterface("Interface.IPlugin");
                        if (iface != null)
                        {
                            Interface.IPlugin plugin = (Interface.IPlugin)Activator.CreateInstance(type);
                            plugin.Host = Program.pluginServices;
                            Plugins.Add(plugin.Name, plugin);
                        }
                    }
                }
            catch (Exception e)
            {
                Logger.txtLogger.WriteMessage("Error loading plugin." + e.ToString());
            }
        }
    }
}
